angular.module("application.services")
.factory('mapTimelineProcess', function($http, $q, renderProcess, BASE_URL) 
{
	var myStyle = [{"featureType":"road","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"administrative","elementType":"geometry","stylers":[{"visibility":"on"},{"weight":0.8},{"color":"#DAD5CC"}]},{"featureType":"administrative.country","elementType":"geometry.stroke","stylers":[{"weight":0.8},{"color":"#b16736"}]},{"featureType":"administrative","elementType":"labels","stylers":[{"weight":0.1},{"color":"#e1e1e1"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#f0ece6"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"transit","stylers":[{"visibility":"off"}]}];
	var infowLast = null;
	var linkEvent = {};
	var bigMap = null;
	var mRegion = "";
	var mapConfig = [
		{center: {lat: 15.961329, lng: 106.259766}, zoom: 5},
		{center: {lat: 38.5997, lng: 51.5039 }, zoom: 2}
	]

	var abortHttp = $q.defer();

	return {
		initialMap: function(region) {
			var v = null; mRegion = region;
			if(region == 'vn') {
				v = mapConfig[0];
			}
			else {
				v = mapConfig[1];
			}

			// Initialize Static Map
			var mapOptions = {
				mapTypeControlOptions: {
					mapTypeIds: ['mystyle', google.maps.MapTypeId.TERRAIN]
				},
				// scrollwheel: false,
				mapTypeId: 'mystyle',
				// disableDoubleClickZoom: true,
				mapTypeControl: false,
				zoomControl: true,
				streetViewControl: false,

				center: v.center,
				zoom: v.zoom
			};
			bigMap = new google.maps.Map(document.getElementById("bigmap"),mapOptions);
			bigMap.mapTypes.set('mystyle',new google.maps.StyledMapType(myStyle,{ name:'My Style'}));
			google.maps.event.addListener(bigMap, 'click', function(event) {
				if(infowLast) infowLast.close();
			});
			google.maps.event.addDomListener(window, "resize", function() {
				google.maps.event.trigger(bigMap, "resize");
			});
			return bigMap;
		},

		getData: function(region) {
			var deferred = $q.defer();
			var events = $http.post(BASE_URL + 'index.php/application_api/timeline/getEventData');
			var time = $http.post(BASE_URL + 'index.php/application_api/timeline/getEventTime/' + region);
			
			$q.all([events, time]).then(function(data) {
				
				deferred.resolve({
					events: data[0],
					times: data[1]
				});
			});
			return deferred.promise;
		},

		slidersInit: function() {
			$('#centuries-frame').sly({
				horizontal: 1,
				itemNav: 'forceCentered',
				activateMiddle: 1, // forceCentered only
				activateOn: 'click',
				smart: 1,
				mouseDragging: 1,
				touchDragging: 1,
				// releaseSwing: 1,
				scrollBar: $('#c-scrollbar'),
				scrollBy: 1,
				speed: 300,
				elasticBounds: 1,
				easing: 'easeOutExpo',
				dragHandle: 1,
				dynamicHandle: 1,
				clickBar: 1,
			});
			$('#years-frame').sly({
				horizontal: 1,
				itemNav: 'forceCentered',
				activateMiddle: 1, // forceCentered only
				activateOn: 'click',
				smart: 1,
				mouseDragging: 1,
				touchDragging: 1,
				releaseSwing: 1,
				scrollBar: $('#y-scrollbar'),
				scrollBy: 1,
				speed: 300,
				elasticBounds: 1,
				easing: 'easeOutExpo',
				dragHandle: 1,
				dynamicHandle: 1,
				clickBar: 1,
			});
		},

		makeTimeline: function(timeData) {
			var timeline = [];

			// Create Centuries Array
			centArr = [];
			for(obj in timeData) {
				cN = timeData[obj]['from']['century'];
				dup = false;
				for(i in centArr) {
					if(cN == centArr[i]) dup = true;
				}
				if(!dup) centArr.push(cN);

				if(timeData[obj]['to'] != null) {
					cN = timeData[obj]['to']['century'];
					dup = false;
					for(i in centArr) {
						if(cN == centArr[i]) dup = true;
					}
					if(!dup) centArr.push(cN);
				}
			}
			centArr.sort(sortNumber);

			// Push Centuries Array to Timeline
			for(i in centArr) {
				lbl = renderProcess.makeCenturyCaption(centArr[i]);
				a = {};
				a.val = centArr[i];
				a.str = lbl;
				a.years = [];
				timeline.push(a);
			}

			// Create Years Array
			yearArr = [];
			for(obj in timeData) {
				yN = timeData[obj]['from']['year'];
				if(yN) {
					dup = false;
					for(i in yearArr) {
						if(yN == yearArr[i]) dup = true;
					}
					if(!dup) yearArr.push(yN);
				}

				if(timeData[obj]['to'] != null) {
					yN = timeData[obj]['to']['year'];
					if(yN) {
						dup = false;
						for(i in centArr) {
							if(yN == centArr[i]) dup = true;
						}
						if(!dup) centArr.push(yN);
					}
				}
			}
			yearArr.sort(sortNumber);
			

			//Add years to Centuries Array
			for(cent in timeline) {
				for(y in yearArr) {
					x = parseInt(yearArr[y]/100);
					if(x >= 0) x++;
					else x--;

					if(x == timeline[cent]['val']) {
						timeline[cent]['years'].push(yearArr[y]);
					}
				}

			}
			return timeline;
		},

		eventsToMap: function(data, century, year, map, type) {
			deferred = $q.defer();
			linkEvent = {};
			var eventArr = [];
			var elementsArr = [];

			abortHttp = $q.defer();
			angular.forEach(data, function(item) {

				arrNation = [];
				if(item.countries && item.countries.length > 0) {
					angular.forEach(item.countries, function(ctr) {
						arrNation.push(ctr.id);
					})
				}

				frCent = item.from.century;
				frYear = item.from.year;

				toCent = null; toYear = null;
				if(item.to) {
					toCent = item.to.century;
					toYear = item.to.year;
				}

				if(type == -1) {
					if(toCent && century <= toCent && century >= frCent) { eventArr.push(item); }
					else if(century == frCent) { eventArr.push(item); }

					if(year) {
						for(i in eventArr) {
							if( (eventArr[i].from.year && eventArr[i].from.year > year) ||
								(!eventArr[i].to && eventArr[i].from.year < year) ||
								(eventArr[i].to && eventArr[i].to.year && eventArr[i].to.year < year))
							{
								eventArr.splice(i, 1);
							}
						}
					}
				}
				else if(type != 0) {
					paramFrYear = century;
					paramFrCentury = Math.floor(paramFrYear / 100);
					if(paramFrCentury >= 0) paramFrCentury++;

					paramToYear = year;
					paramToCentury = Math.floor(paramToYear / 100);
					if(paramToCentury >= 0) paramToCentury++;

					if(toCent && toCent >= paramFrCentury && frCent <= paramToCentury) { 
						if(arrNation.indexOf(type) != -1)
							eventArr.push(item); 
					}
					else if(frCent >= paramFrCentury && frCent <= paramToCentury) { 
						if(arrNation.indexOf(type) != -1)
							eventArr.push(item); }

					for(i in eventArr) {
						if( (eventArr[i].to && eventArr[i].to.year && eventArr[i].to.year < paramFrYear) ||
							(eventArr[i].from.year && eventArr[i].from.year > paramToYear) ||
							(eventArr[i].to && !eventArr[i].to.year && eventArr[i].from.year && eventArr[i].from.year < paramFrYear))
						{
							eventArr.splice(i, 1);
						}
					}
				}
				else {
					paramFrYear = century;
					paramFrCentury = Math.floor(paramFrYear / 100);
					if(paramFrCentury >= 0) paramFrCentury++;

					paramToYear = year;
					paramToCentury = Math.floor(paramToYear / 100);
					if(paramToCentury >= 0) paramToCentury++;

					if(toCent && toCent >= paramFrCentury && frCent <= paramToCentury) { 
							eventArr.push(item); 
					}
					else if(frCent >= paramFrCentury && frCent <= paramToCentury) { 
							eventArr.push(item); }

					for(i in eventArr) {
						if( (eventArr[i].to && eventArr[i].to.year && eventArr[i].to.year < paramFrYear) ||
							(eventArr[i].from.year && eventArr[i].from.year > paramToYear) ||
							(eventArr[i].to && !eventArr[i].to.year && eventArr[i].from.year && eventArr[i].from.year < paramFrYear))
						{
							eventArr.splice(i, 1);
						}
					}
				}
			});

			// Create list event array - container of map elements by event-id
			console.log(eventArr);
			angular.forEach(eventArr, function(item) {
				eventId = item._id.$id;
				linkEvent[eventId] = [[],[]];
			});

			// Load Marker, Polygon,... to Maps ===================================================
			angular.forEach(eventArr, function(event) {
					// Markers -----------
					if(event.points.length > 0) {
						points = event.points;

						for(i in points) {
							latlng = new google.maps.LatLng(points[i].latlng[0],points[i].latlng[1]);
							var marker = new google.maps.Marker({
								position: latlng,
								map: map,
								title: event.eventName
							});
							elementsArr.push(marker);
							linkEvent[event._id.$id][0].push(marker);

							// Circle --------
							var circle = new google.maps.Circle({
								center: latlng,
								strokeWeight: 1,
								strokeColor: '#8E44AD',
								strokeOpacity: 0.8,
								fillColor: '#9B59B6',
								fillOpacity: 0.3,
								radius: points[i].radius,
								map: map
							});
							elementsArr.push(circle);

							strContent = '<div class="map-content">' +
							'<h3 class="event">' + event.eventName + '</h3>' +
							'<p class="position">Khu vực: ' + points[i].posName + '</p>' +
							'<p class="link"><a href="#/event/' + event._id.$id + '">Những bài học liên quan</a></p>' +
							'</div>';
							var infowindowM = new google.maps.InfoWindow({ content: strContent });
							elementsArr.push(infowindowM);

							google.maps.event.addListener(marker,'click', (function (marker,strContent,infowindowM){ 
								return function() {
									if(infowLast) infowLast.close();
									infowindowM.setContent(strContent);
									infowindowM.open(map,marker);
									infowLast = infowindowM;
								};
							})(marker,strContent,infowindowM));
							google.maps.event.addListener(circle,'click', (function (marker,strContent,infowindowM) { 
								return function() {
									if(infowLast) infowLast.close();
									infowindowM.setContent(strContent);
									infowindowM.open(map,marker);
									infowLast = infowindowM;
								};
							})(marker,strContent,infowindowM));
						}
					}

					// Polygon -----------
					// console.log(event.polygons);
					if(event.polygons.length > 0) {

						// linkEvent[event._id.$id][1] = [];

						polygons = event.polygons;
						for(poly in polygons) {
							var coordinate = [];
							latlngs = polygons[poly].latlng.split(" ");
							for(i in latlngs) {
								x = latlngs[i].split(',');
								y = new google.maps.LatLng(x[0], x[1]);
								coordinate.push(y);
							}
							var polygon = new google.maps.Polygon({
								path: coordinate,
								strokeWeight: 1,
								strokeOpacity: 0.6,
								strokeColor: polygons[poly].color,
								fillColor: polygons[poly].color,
								fillOpacity: 0.2,
								map: map,
								title: event.eventName
							});
							elementsArr.push(polygon);
							linkEvent[event._id.$id][1].push(polygon);

							strContent = '<div class="map-content">' +
							'<h3 class="event">' + event.eventName + '</h3>' +
							'<p class="position">Khu vực: ' + polygons[poly].posName + '</p>' +
							'<p class="link"><a href="#/event/' + event._id.$id + '">Những bài học liên quan</a></p>' +
							'</div>';
							var infowindow = new google.maps.InfoWindow({ content: strContent });
							elementsArr.push(infowindow);

							// Get center of Polygon ----
							bounds = new google.maps.LatLngBounds();
							for(i = 0; i < coordinate.length; i++) {
								bounds.extend(coordinate[i]);
							}
							polyCenter = bounds.getCenter();

							google.maps.event.addListener(polygon,'click', (function(polygon,strContent,infowindow,polyCenter){ 
								return function() {
									if(infowLast) infowLast.close();
									infowindow.setContent(strContent);
									infowindow.setPosition(polyCenter);
									infowindow.open(map);
									infowLast = infowindow;
								};
							})(polygon,strContent,infowindow,polyCenter));
						}
					}
					
					// Provinces
					if(event.provinces && event.provinces.length > 0) {

						// linkEvent[event._id.$id][1] = [];

						ids = [];
						angular.forEach(event.provinces, function(prov) {
							ids.push(prov.id);						
						});

						$http({
							url: BASE_URL + 'index.php/application_api/timeline/getProvinces',
							method: "POST",
							data: $.param({"ids": ids}),
							timeout: abortHttp.promise,
							headers: {'Content-Type': 'application/x-www-form-urlencoded'}
						}).success(function(result) {
							// Polygons

							angular.forEach(event.provinces, function(prov) {
								strCoordinates = result[prov.id];
								coordinates = [];

								angular.forEach(strCoordinates.polygons, function(coor) {
									var coors = [];
									latlngs = coor.split(" ");
									for(i in latlngs) {
										x = latlngs[i].split(',');
										y = new google.maps.LatLng(x[1], x[0]);
										coors.push(y);
									}
									coordinates.push(coors);
									var polygon = new google.maps.Polygon({
										path: coors,
										strokeWeight: 1,
										strokeOpacity: 0.6,
										strokeColor: "#FF9900",
										fillColor: "#FF9900",
										fillOpacity: 0.2,
										map: map,
										title: prov.eventName
									});
									elementsArr.push(polygon);
									linkEvent[event._id.$id][1].push(polygon);

									strContent = '<div class="map-content">' +
									'<h3 class="event">' + event.eventName + '</h3>' +
									'<p class="position">Khu vực: ' + prov.posName + '</p>' +
									'<p class="link"><a href="#/event/' + event._id.$id + '">Những bài học liên quan</a></p>' +
									'</div>';
									var infowindow = new google.maps.InfoWindow({ content: strContent });
									elementsArr.push(infowindow);

									// Get center of Polygon ----
									bounds = new google.maps.LatLngBounds();
									angular.forEach(coordinates, function(coors) {
										for(i in coors) {
											bounds.extend(coors[i]);
										}
									});
									polyCenter = bounds.getCenter();

									google.maps.event.addListener(polygon,'click', (function(polygon,strContent,infowindow,polyCenter){ 
										return function() {
											if(infowLast) infowLast.close();
											infowindow.setContent(strContent);
											infowindow.setPosition(polyCenter);
											infowindow.open(map);
											infowLast = infowindow;
										};
									})(polygon,strContent,infowindow,polyCenter));
								});
							});
						});		
					}

					// Countries
					if(event.countries && event.countries.length > 0) {

						// linkEvent[event._id.$id][1] = [];

						ids = [];
						// Event = event;
						// var countries = event.countries;

						angular.forEach(event.countries, function(country) {
							ids.push(country.id);						
						});

						$http({
							url: BASE_URL + 'index.php/application_api/timeline/getCountries',
							method: "POST",
							data: $.param({"ids": ids}),
							timeout: abortHttp.promise,
							headers: {'Content-Type': 'application/x-www-form-urlencoded'}
						}).success(function(result) {
							// Polygons
							console.log(result);
							angular.forEach(event.countries, function(country) {
								strCoordinates = result[country.id];
								coordinates = [];

								angular.forEach(strCoordinates.polygons, function(coor) {
									var coors = [];
									latlngs = coor.split(" ");
									for(i in latlngs) {
										x = latlngs[i].split(',');
										y = new google.maps.LatLng(x[1], x[0]);
										coors.push(y);
									}
									coordinates.push(coors);
									var polygon = new google.maps.Polygon({
										path: coors,
										strokeWeight: 1,
										strokeOpacity: 0.6,
										strokeColor: "#FF9900",
										fillColor: "#FF9900",
										fillOpacity: 0.2,
										map: map,
										title: country.eventName
									});
									elementsArr.push(polygon);
									linkEvent[event._id.$id][1].push(polygon);

									strContent = '<div class="map-content">' +
									'<h3 class="event">' + event.eventName + '</h3>' +
									'<p class="position">Khu vực: ' + country.posName + '</p>' +
									'<p class="link"><a href="#/event/' + event._id.$id + '">Những bài học liên quan</a></p>' +
									'</div>';
									var infowindow = new google.maps.InfoWindow({ content: strContent });
									elementsArr.push(infowindow);

									// Get center of Polygon ----
									bounds = new google.maps.LatLngBounds();
									angular.forEach(coordinates, function(coors) {
										for(i in coors) {
											bounds.extend(coors[i]);
										}
									});
									polyCenter = bounds.getCenter();

									google.maps.event.addListener(polygon,'click', (function(polygon,strContent,infowindow,polyCenter){ 
										return function() {
											if(infowLast) infowLast.close();
											infowindow.setContent(strContent);
											infowindow.setPosition(polyCenter);
											infowindow.open(map);
											infowLast = infowindow;
										};
									})(polygon,strContent,infowindow,polyCenter));
								});
							});
						});	

					}

					if(mRegion == 'vn') {
						map.setZoom(mapConfig[0].zoom);
						map.setCenter(mapConfig[0].center);
					}
					else {
						map.setZoom(mapConfig[1].zoom);
						map.setCenter(mapConfig[1].center);
					}
					// alert(mRegion);
				// })(event);
			});

			// return elementsArr;
			deferred.resolve(elementsArr);
			return deferred.promise;
		},
		abortMapHttp: function() {
			abortHttp.resolve('canceled Https');
		},
		changeView: function(evId) {
			// If view all events
			if(evId == 'all') {
				var isZoom = false;
				bound = new google.maps.LatLngBounds();
				angular.forEach(linkEvent, function(ev) 
				{
					angular.forEach(ev[0], function(marker) {
						marker.setVisible(true);
						dot = marker.getPosition();
						bound.extend(dot);
					});

					angular.forEach(ev[1], function(polygon) {
						polygon.setVisible(true);
						paths = polygon.getPaths();
						for(i = 0; i < paths.getLength(); i++) {
							p = paths.getAt(i);
							for(j = 0; j < p.getLength(); j++) {
								bound.extend(p.getAt(j));
							}
						}
					});
				});	

				bigMap.panTo(bound.getCenter());
				google.maps.event.addListenerOnce(bigMap, 'idle', function(){
					setTimeout(function() {
						if(!isZoom) {
							bigMap.fitBounds(bound);
						}
						isZoom = true;
					}, 100);
					
				});
				return null;
			}

			// If event don't have any mapelement
			console.log(linkEvent);
			if(linkEvent[evId][0].length == 0 && linkEvent[evId][1] == 0 && evId != 'all')
				return null;

			// Othewise
			angular.forEach(linkEvent, function(ev) {
				if(linkEvent[evId] != ev) {
					angular.forEach(ev[0], function(marker) {
						marker.setVisible(false);
					});
					angular.forEach(ev[1], function(polygon) {
						polygon.setVisible(false);
					});
				}
			});

			var isZoom = false;
			bound = new google.maps.LatLngBounds();

			angular.forEach(linkEvent[evId][0], function(marker) {
				marker.setVisible(true);
				dot = marker.getPosition();
				bound.extend(dot);
			});

			angular.forEach(linkEvent[evId][1], function(polygon) {
				polygon.setVisible(true);
				paths = polygon.getPaths();
				for(i = 0; i < paths.getLength(); i++) {
					p = paths.getAt(i);
					for(j = 0; j < p.getLength(); j++) {
						bound.extend(p.getAt(j));
					}
				}
			});

			bigMap.panTo(bound.getCenter());
			google.maps.event.addListenerOnce(bigMap, 'idle', function(){
				setTimeout(function() {
					if(!isZoom) {
						bigMap.fitBounds(bound);
					}
					isZoom = true;
				}, 100);
					
			});
		},
		getListNation: function() {
			return $http.post(BASE_URL + 'index.php/application_api/timeline/getAllCountries').success(function(data) {
				return data;
			});
		}
	};

	//Functions =====================================================
	function sortNumber(a,b) {
		return a - b;
	}
	function closeInfoWindow(list) {
		if(list.length > 0) {
			for(i in list) {
				list[i].close();
			}
		}
	}
})
//=====================================================================================================================
//=====================================================================================================================
//=====================================================================================================================
.factory('renderProcess', function() {
	return {
		setListHeight: function() {
			pHeight = $('#main-content .event-list').height();
			$('.event-list ul.list').css('height', pHeight - 60);

			$(window).resize(function() {
				pHeight = $('#main-content .event-list').height();
				$('.event-list ul.list').css('height', pHeight - 60);
			})
		},
		makeCenturyCaption: function(num) {
			return centCaption(num);
		}
	}

	//Functions =====================================================
	function centCaption(number) {
		// if(number == null) return null;
		
		var centArr = ['I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII','XIII','XIV','XV','XVI','XVII','XVIII','XIX','XX','XXI'];
		var str;
		if(number <= -100000 ) {
			var x = number / 1000;
			str = "Cách đây hàng chục triệu năm";
			return str;
		}
		else if(number <= -10000 ) {
			var x = number / 1000;
			str = "Cách đây khoảng " + -x + " triệu năm";
			return str;
		}
		else if(number <= -200 ) {
			var x = number / 100;
			str = "Cách đây khoảng " + -x + " vạn năm";
			return str;
		}
		else if (number <= -10) {
			var x = number * 100;
			str = "Cách đây " + -x + " năm";
			return str;
		}
		else {
			x = Math.abs(number);
			if(number < 0) {
				str = "Thế kỷ " + centArr[x-1] + " - TCN";
			}
			else str = "Thế kỷ " + centArr[x-1];
			return str;
		}
	}
});
